<?php
/**
 * 面向对象的websocket客户端.
 * User: mac
 * Date: 2019-02-28
 * Time: 22:56
 */

class task
{
    const HOST = '0.0.0.0';
    const PORT = '9502';
    public $ws = null;

    public function __construct()
    {
        //实例化一个websocket服务器
        $this->ws = new swoole_websocket_server(self::HOST, self::PORT);
        //设置参数,使用task任务时，必须设置task_worker_num
        $this->ws->set([
            'task_worker_num' => 8 //设置task进程数量
        ]);
        //注册open message task finish  close 方法
        $this->ws->on('open', [$this, 'onOpen']);
        $this->ws->on('message', [$this, 'onMessage']);
        //使用task任务时，必须设置task和finish的回调
        $this->ws->on('task', [$this, 'onTask']);
        $this->ws->on('finish', [$this, 'onFinish']);
        $this->ws->on('close', [$this, 'onClose']);
        //启动服务
        $this->ws->start();
    }

    public function onOpen($ws, $requeset)
    {
        var_dump($requeset);
        $ws->push($requeset->fd, 'hello, welcome' . PHP_EOL);
    }

    public function onMessage($ws, $frame)
    {
        echo 'receive message ' . $frame->data . PHP_EOL;
        $data = array(
            'fd' => $frame->fd,
            'task' => 1
        );
        $ws->task($data);
        $ws->push($frame->fd, 'send message ' . date('Y-m-d H:i:s'));
    }

    /**
     * @param $serv
     * @param $taskId  int 任务ID
     * @param $workId  int work进程ID
     * @param $data  string 投递的任务参数
     * @return array
     */
    public function onTask($serv, $taskId, $workId, $data)
    {
        var_dump($taskId, $workId, $data);
        sleep(10);
        $task_rsp = array(
            'fd' => $data['fd'],
            'msg' => 'success'
        );
        return $task_rsp;  //告诉onFinish
    }

    /**
     * @param $serv
     * @param $taskId
     * @param $data string 这个data是onTask返回的数据，而不是投递任务的参数
     */
    public function onFinish($serv, $taskId, $data)
    {
        echo "taskId: {$taskId}\n";
        $serv->push($data['fd'], $data['msg']);
    }

    public function onClose($ws, $fd)
    {
        echo $fd . ' client close' . PHP_EOL;
    }
}

$ws = new task();